package com.common.dingding.controller;

import com.common.dingding.common.Result;
import com.common.dingding.entity.DingTalkUser;
import com.common.dingding.entity.SchedulingRecord;
import com.common.dingding.service.DingTalkService;
import com.common.dingding.service.SchedulingRecordService;
import com.common.dingding.utils.JwtUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 排班管理控制器
 */
@RestController
@RequestMapping("/api/scheduling")
@Tag(name = "排班管理", description = "排班相关接口")
public class SchedulingController {

    @Autowired
    private SchedulingRecordService schedulingRecordService;

    @Autowired
    private DingTalkService dingTalkService;

    @Autowired
    private JwtUtils jwtUtils;

    /**
     * 保存排班记录
     * @param record 排班记录
     * @param authorization Authorization header
     * @return 操作结果
     */
    @PostMapping
    @Operation(summary = "保存排班记录", description = "保存单个排班记录")
    public Result<String> saveScheduling(@RequestBody SchedulingRecord record, @RequestHeader("Authorization") String authorization) {
        try {
            // 从token中获取当前用户ID
            String currentUserId = getCurrentUserId(authorization);
            record.setCreateBy(currentUserId);
            
            // TODO: 实现权限控制，确保当前用户有权限对该用户进行排班
            // 1. 获取当前用户的角色
            // 2. 获取当前用户的组织
            // 3. 获取被排班用户的组织
            // 4. 根据角色判断是否有权限
            
            // 从钉钉获取用户详细信息
            Map<String, Object> userInfo = dingTalkService.getUserDetailById(record.getUserId(), getAccessToken());
            record.setName((String) userInfo.get("name"));
            record.setPhone((String) userInfo.get("mobile"));
            
            // 获取用户组织信息
            Map<String, Object> orgInfo = dingTalkService.getUserOrgId(record.getUserId());
            record.setOrgId((String) orgInfo.get("orgId"));
            record.setOrgName((String) orgInfo.get("orgName"));
            
            boolean success = schedulingRecordService.saveScheduling(record);
            if (success) {
                return Result.success("排班成功");
            } else {
                return Result.fail("排班失败");
            }
        } catch (Exception e) {
            return Result.fail("排班失败: " + e.getMessage());
        }
    }

    /**
     * 批量保存排班记录
     * @param request 批量排班请求
     * @param authorization Authorization header
     * @return 操作结果
     */
    @PostMapping("/batch")
    @Operation(summary = "批量保存排班记录", description = "批量保存多个排班记录")
    public Result<String> saveBatchScheduling(@RequestBody BatchSchedulingRequest request, @RequestHeader("Authorization") String authorization) {
        try {
            // 从token中获取当前用户ID
            String currentUserId = getCurrentUserId(authorization);
            String accessToken = getAccessToken();
            List<SchedulingRecord> records = new ArrayList<>();
            
            // 遍历需要排班的用户
            for (DingTalkUser user : request.getUsers()) {
                SchedulingRecord record = new SchedulingRecord();
                record.setUserId(user.getUserid());
                record.setName(user.getName());
                record.setPhone(user.getMobile());
                record.setScheduleDate(request.getScheduleDate());
                record.setCreateBy(currentUserId);
                record.setIsAdmin(user.getIsAdmin());
                record.setIsBoss(user.getIsBoss());
                record.setIsLeader(user.getIsLeader());


                // 获取用户组织信息
                List<Long> Departs = user.getDepartment();
                String orgId = Departs.get(0).toString();
                Map<String, Object> orgInfo = dingTalkService.getOrganizationDetail(orgId);
                record.setOrgId(orgInfo.get("id").toString());
                record.setOrgName((String) orgInfo.get("name"));
                
                records.add(record);
            }
            
            // TODO: 实现权限控制，确保当前用户有权限对这些用户进行排班
            // 1. 获取当前用户的角色
            // 2. 获取当前用户的组织
            // 3. 获取被排班用户的组织
            // 4. 根据角色判断是否有权限
            
            boolean success = schedulingRecordService.saveBatchScheduling(records);
            if (success) {
                return Result.success("批量排班成功");
            } else {
                return Result.fail("批量排班失败");
            }
        } catch (Exception e) {
            return Result.fail("批量排班失败: " + e.getMessage());
        }
    }
    
    /**
     * 批量排班请求参数
     */
    @Data
    private static class BatchSchedulingRequest {
        private LocalDate scheduleDate; // 排班日期
        private List<DingTalkUser> users; // 需要排班的用户列表
    }
    
    /**
     * 获取钉钉AccessToken
     * @return AccessToken
     */
    private String getAccessToken() {
        // 反射调用DingTalkService中的getAccessToken方法
        try {
            java.lang.reflect.Method method = dingTalkService.getClass().getDeclaredMethod("getAccessToken");
            method.setAccessible(true);
            return (String) method.invoke(dingTalkService);
        } catch (Exception e) {
            throw new RuntimeException("获取AccessToken失败: " + e.getMessage(), e);
        }
    }

    /**
     * 删除排班记录
     * @param userId 用户ID
     * @param scheduleDate 排班日期
     * @param authorization Authorization header
     * @return 操作结果
     */
    @DeleteMapping
    @Operation(summary = "删除排班记录", description = "删除指定用户在指定日期的排班记录")
    public Result<String> deleteScheduling(@RequestParam String userId, @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate scheduleDate, @RequestHeader("Authorization") String authorization) {
        try {
            // TODO: 实现权限控制，确保当前用户有权限删除该排班记录
            
            // 从token中获取当前用户ID作为删除人
            String deleteBy = getCurrentUserId(authorization);
            
            boolean success = schedulingRecordService.deleteScheduling(userId, scheduleDate, deleteBy);
            if (success) {
                return Result.success("删除排班记录成功");
            } else {
                return Result.fail("删除排班记录失败");
            }
        } catch (Exception e) {
            return Result.fail("删除排班记录失败: " + e.getMessage());
        }
    }

    /**
     * 查询某天的排班记录
     * @param scheduleDate 排班日期
     * @param authorization Authorization header
     * @return 排班记录列表
     */
    @GetMapping("/daily")
    @Operation(summary = "查询某天的排班记录", description = "查询指定日期的排班记录")
    public Result<List<SchedulingRecord>> getDailyScheduling(@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate scheduleDate, @RequestHeader("Authorization") String authorization) {
        try {
            Map<String, Object> info = getRoleAndUserId(authorization);
            // TODO: 实现权限控制，获取当前用户可以查看的用户ID列表
            List<Map<String, Object>> users= getManageableUserIds((String) info.get("UserId"), (Boolean) info.get("isWorkshopScheduler"),(Boolean)info.get("isScheduler"));
            List<String> userIds = users.stream()
                    .map(user -> (String) user.get("userid"))
                    .collect(java.util.stream.Collectors.toList());

            List<SchedulingRecord> records = schedulingRecordService.getSchedulingByDate(scheduleDate, userIds);
            return Result.success(records, "查询成功");
        } catch (Exception e) {
            return Result.fail("查询失败: " + e.getMessage());
        }
    }

    /**
     * 查询某月每天的排班人数
     * @param year 年份
     * @param month 月份
     * @param authorization Authorization header
     * @return 每天的排班人数，key为日期，value为人数
     */
    @GetMapping("/monthly/count")
    @Operation(summary = "查询某月每天的排班人数", description = "查询指定月份每天的排班人数")
    public Result<Map<String, Integer>> getMonthlyDailyCount(@RequestParam int year, @RequestParam int month, @RequestHeader("Authorization") String authorization) {
        try {
            // 从token中获取当前用户ID
            Map<String, Object> info = getRoleAndUserId(authorization);
            // TODO: 实现权限控制，获取当前用户可以查看的用户ID列表
            List<Map<String, Object>> users= getManageableUserIds((String) info.get("UserId"), (Boolean) info.get("isWorkshopScheduler"),(Boolean)info.get("isScheduler"));
            List<String> userIds = users.stream()
                    .map(user -> (String) user.get("userid"))
                    .collect(java.util.stream.Collectors.toList());
            
            Map<String, Integer> dailyCount = schedulingRecordService.getDailyCountByMonth(year, month, userIds);
            return Result.success(dailyCount, "查询成功");
        } catch (Exception e) {
            return Result.fail("查询失败: " + e.getMessage());
        }
    }

    /**
     * 查询用户本人今天是否排班
     * @param authorization Authorization header
     * @return 排班状态
     */
    @GetMapping("/today")
    @Operation(summary = "查询本人今天是否排班", description = "查询当前用户今天是否排班")
    public Result<Map<String, Object>> getTodayScheduling(@RequestHeader("Authorization") String authorization) {
        try {
            // 从token中获取当前用户ID
            String currentUserId = getCurrentUserId(authorization);
            
            LocalDate today = LocalDate.now();
            boolean isScheduled = schedulingRecordService.isScheduled(currentUserId, today);
            
            Map<String, Object> result = Map.of(
                    "today", today,
                    "isScheduled", isScheduled
            );
            
            return Result.success(result, "查询成功");
        } catch (Exception e) {
            return Result.fail("查询失败: " + e.getMessage());
        }
    }

    /**
     * 查询用户本人下一次排班日期
     * @param authorization Authorization header
     * @return 下一次排班日期
     */
    @GetMapping("/next")
    @Operation(summary = "查询本人下一次排班日期", description = "查询当前用户下一次排班日期")
    public Result<Map<String, Object>> getNextScheduling(@RequestHeader("Authorization") String authorization) {
        try {
            // 从token中获取当前用户ID
            String currentUserId = getCurrentUserId(authorization);
            
            LocalDate nextDate = schedulingRecordService.getNextScheduleDate(currentUserId);
            
            Map<String, Object> result = Map.of(
                    "nextScheduleDate", nextDate
            );
            
            return Result.success(result, "查询成功");
        } catch (Exception e) {
            return Result.fail("查询失败: " + e.getMessage());
        }
    }


    /**
     * 查询待排班人员及组织机构
     * @param authorization Authorization header
     * @return 待排班人员及组织机构
     */
    @GetMapping("/schedulingUsersAndOrg")
    @Operation(summary = "查询待排班人员及组织机构", description = "查询待排班人员及组织机构")
    public Result<List<Map<String, Object>>> getSchedulingUsersAndOrg(@RequestHeader("Authorization") String authorization) {
        try {
            // 从token中获取当前用户ID
            Map<String, Object> info = getRoleAndUserId(authorization);

            //获取下级组织机构及用户
            List<Map<String, Object>> result = dingTalkService.getManageableUserIdsAndOrg((String) info.get("UserId"), (Boolean) info.get("isWorkshopScheduler"),(Boolean)info.get("isScheduler"));
            return Result.success(result, "查询成功");
        } catch (Exception e) {
            return Result.fail("查询失败: " + e.getMessage());
        }
    }

    /**
     * 查询待排班人员及组织机构
     * @param authorization Authorization header
     * @return 待排班人员及组织机构
     */
    @GetMapping("/getUsersAndOrgByOrgId")
    @Operation(summary = "查询待排班人员及组织机构（提供组织机构id）", description = "查询待排班人员及组织机构（提供组织机构id）")
    public Result<List<Map<String, Object>>> getUsersAndOrgByOrgId(@RequestHeader("Authorization") String authorization,@RequestParam String OrgId) {
        try {
            // 从token中获取当前用户ID
            Map<String, Object> info = getRoleAndUserId(authorization);
            //获取下级组织机构及用户
//            List<Map<String, Object>> result = dingTalkService.getManageableUserIdsAndOrg((String) info.get("UserId"), (Boolean) info.get("isWorkshopScheduler"),(Boolean)info.get("isScheduler"));
            List<Map<String, Object>> result =  dingTalkService.getUsersByOrganization(OrgId);
            List<Map<String, Object>> OrgList = dingTalkService.getOrganizationsByParentId(OrgId);
            result.addAll(OrgList);
            return Result.success(result, "查询成功");
        } catch (Exception e) {
            return Result.fail("查询失败: " + e.getMessage());
        }
    }

    /**
     * 从Authorization header中获取当前用户ID
     * @param authorization Authorization header
     * @return 当前用户ID
     */
    private String getCurrentUserId(String authorization) {
        String token = authorization.replace("Bearer ", "");
        return jwtUtils.getUserIdFromToken(token);
    }
    /**
     * 从Authorization header中获取当前用户ID
     * @param authorization Authorization header
     * @return 当前用户信息
     */
    private Map<String, Object> getCurrentUserInfo(String authorization) {
        String token = authorization.replace("Bearer ", "");
        Map<String, Object> userInfo = jwtUtils.parseToken(token);
        return userInfo;
    }

    private List<String> getCurrentUserRole(Map<String, Object> userInfo) {
        List<String> roles = new ArrayList<>();
        List<Map<String, Object>> list = (List<Map<String, Object>>) userInfo.get("roles");
        for (Map<String, Object> role : list) {
//            Map<String, Object> role = (Map<String, Object>) roleInfo.get("role");
            String roleName = (String) role.get("name");
            roles.add(roleName);
        }
        return roles;
    }


    /**
     * 获取当前用户可以管理的用户ID列表
     * @param currentUserId 当前用户ID
     * @return 可以管理的用户ID列表
     */
    private List<Map<String, Object>> getManageableUserIds(String currentUserId,boolean isWorkshopScheduler,boolean isScheduler) {
        return dingTalkService.getManageableUserIds(currentUserId,isWorkshopScheduler,isScheduler);
    }
    /**
     * 获取当前用户id和角色相关信息
     * UserId
     * isWorkshopScheduler  是否车间排班管理员
     * isScheduler 是否排班管理员
     */
    private Map<String, Object> getRoleAndUserId(String authorization){
        Map<String, Object> res = new HashMap<>();
        Map<String, Object> info = getCurrentUserInfo(authorization);
        List<String> roles = getCurrentUserRole(info);
        String currentUserId = (String) info.get("userid");
        // 检查用户角色
        boolean isWorkshopScheduler = roles.contains("车间排班管理员");
        boolean isScheduler = roles.contains("排班管理员");
        res.put("UserId",currentUserId);
        res.put("isWorkshopScheduler",isWorkshopScheduler);
        res.put("isScheduler",isScheduler);
        return res;
    }
}